﻿using System;
using System.Collections.Generic;
using UnityEngine;

// Token: 0x02000009 RID: 9
[AddComponentMenu("Dynamic Bone/Dynamic Bone Ver01")]
public class DynamicBone_Ver01 : MonoBehaviour
{
	// Token: 0x06000023 RID: 35 RVA: 0x00003E3C File Offset: 0x0000203C
	public virtual void Start()
	{
		this.SetupParticles();
	}

	// Token: 0x06000024 RID: 36 RVA: 0x00003E44 File Offset: 0x00002044
	public virtual void Update()
	{
		if (this.m_Weight > 0f)
		{
			this.InitTransforms();
		}
	}

	// Token: 0x06000025 RID: 37 RVA: 0x00003E5C File Offset: 0x0000205C
	public virtual void LateUpdate()
	{
		if (this.m_Weight > 0f)
		{
			this.UpdateDynamicBones(Time.deltaTime);
		}
	}

	// Token: 0x06000026 RID: 38 RVA: 0x00003E7C File Offset: 0x0000207C
	public virtual void OnEnable()
	{
		this.ResetParticlesPosition();
		this.m_ObjectPrevPosition = base.transform.position;
	}

	// Token: 0x06000027 RID: 39 RVA: 0x00003E98 File Offset: 0x00002098
	public virtual void OnDisable()
	{
		this.InitTransforms();
	}

	// Token: 0x06000028 RID: 40 RVA: 0x00003EA0 File Offset: 0x000020A0
	public virtual void OnValidate()
	{
		this.m_UpdateRate = Mathf.Max(this.m_UpdateRate, 0f);
		this.m_Damping = Mathf.Clamp01(this.m_Damping);
		this.m_Elasticity = Mathf.Clamp01(this.m_Elasticity);
		this.m_Stiffness = Mathf.Clamp01(this.m_Stiffness);
		this.m_Inert = Mathf.Clamp01(this.m_Inert);
		this.m_Radius = Mathf.Max(this.m_Radius, 0f);
		this.m_AddAngleScale = Mathf.Max(this.m_AddAngleScale, 0f);
		if (Application.isEditor && Application.isPlaying)
		{
			this.InitTransforms();
			this.SetupParticles();
		}
	}

	// Token: 0x06000029 RID: 41 RVA: 0x00003F54 File Offset: 0x00002154
	public virtual void OnDrawGizmosSelected()
	{
		if (!base.enabled || this.m_Root == null)
		{
			return;
		}
		if (Application.isEditor && !Application.isPlaying && base.transform.hasChanged)
		{
			this.InitTransforms();
			this.SetupParticles();
		}
		Gizmos.color = Color.white;
		foreach (global::DynamicBone_Ver01.Particle particle in this.m_Particles)
		{
			if (particle.m_ParentIndex >= 0)
			{
				global::DynamicBone_Ver01.Particle particle2 = this.m_Particles[particle.m_ParentIndex];
				Gizmos.DrawLine(particle.m_Position, particle2.m_Position);
			}
			if (particle.m_Radius > 0f)
			{
				Gizmos.DrawWireSphere(particle.m_Position, particle.m_Radius * this.m_ObjectScale);
			}
		}
	}

	// Token: 0x0600002A RID: 42 RVA: 0x00004058 File Offset: 0x00002258
	public virtual void SetWeight(float w)
	{
		if (this.m_Weight != w)
		{
			if (w == 0f)
			{
				this.InitTransforms();
			}
			else if (this.m_Weight == 0f)
			{
				this.ResetParticlesPosition();
				this.m_ObjectPrevPosition = base.transform.position;
			}
			this.m_Weight = w;
		}
	}

	// Token: 0x0600002B RID: 43 RVA: 0x000040B8 File Offset: 0x000022B8
	public virtual float GetWeight()
	{
		return this.m_Weight;
	}

	// Token: 0x0600002C RID: 44 RVA: 0x000040C0 File Offset: 0x000022C0
	public virtual void setRoot(Transform _transRoot)
	{
		this.m_Root = _transRoot;
	}

	// Token: 0x0600002D RID: 45 RVA: 0x000040CC File Offset: 0x000022CC
	public virtual void UpdateDynamicBones(float t)
	{
		if (this.m_Root == null)
		{
			return;
		}
		this.m_ObjectScale = Mathf.Abs(base.transform.lossyScale.x);
		this.m_ObjectMove = base.transform.position - this.m_ObjectPrevPosition;
		this.m_ObjectPrevPosition = base.transform.position;
		int num = 1;
		if (this.m_UpdateRate > 0f)
		{
			float num2 = 1f / this.m_UpdateRate;
			this.m_Time += t;
			num = 0;
			while (this.m_Time >= num2)
			{
				this.m_Time -= num2;
				if (++num >= 3)
				{
					this.m_Time = 0f;
					break;
				}
			}
		}
		if (num > 0)
		{
			for (int i = 0; i < num; i++)
			{
				this.UpdateParticles1();
				this.UpdateParticles2();
				this.m_ObjectMove = Vector3.zero;
			}
		}
		else
		{
			this.SkipUpdateParticles();
		}
		this.ApplyParticlesToTransforms();
	}

	// Token: 0x0600002E RID: 46 RVA: 0x000041E0 File Offset: 0x000023E0
	public virtual void SetupParticles()
	{
		this.m_Particles.Clear();
		if (this.m_Root == null && this.m_Nodes.Count > 0)
		{
			this.m_Root = this.m_Nodes[0].Transform;
		}
		if (this.m_Root == null)
		{
			return;
		}
		this.m_ObjectScale = base.transform.lossyScale.x;
		this.m_ObjectPrevPosition = base.transform.position;
		this.m_ObjectMove = Vector3.zero;
		this.m_BoneTotalLength = 0f;
		global::DynamicBone_Ver01.Particle particle = null;
		int num = -1;
		foreach (global::DynamicBone_Ver01.BoneNode b in this.m_Nodes)
		{
			float boneLength = (particle == null) ? 0f : particle.m_BoneLength;
			particle = this.AppendParticles(b, num, boneLength);
			num++;
		}
		if (this.m_EndLength > 0f || this.m_EndOffset.magnitude != 0f)
		{
			this.AppendParticles(new global::DynamicBone_Ver01.BoneNode(), num, particle.m_BoneLength);
		}
		float num2 = (this.m_Particles.Count > 1) ? (1f / (float)(this.m_Particles.Count - 1)) : 0f;
		float num3 = 0f;
		foreach (global::DynamicBone_Ver01.Particle particle2 in this.m_Particles)
		{
			particle2.m_Damping = this.m_Damping;
			particle2.m_Elasticity = this.m_Elasticity;
			particle2.m_Stiffness = this.m_Stiffness;
			particle2.m_Inert = this.m_Inert;
			particle2.m_Radius = this.m_Radius;
			particle2.m_AddAngleScale = this.m_AddAngleScale;
			if (this.m_DampingDistrib.keys.Length > 0)
			{
				particle2.m_Damping *= this.m_DampingDistrib.Evaluate(num3);
			}
			if (this.m_ElasticityDistrib.keys.Length > 0)
			{
				particle2.m_Elasticity *= this.m_ElasticityDistrib.Evaluate(num3);
			}
			if (this.m_StiffnessDistrib.keys.Length > 0)
			{
				particle2.m_Stiffness *= this.m_StiffnessDistrib.Evaluate(num3);
			}
			if (this.m_InertDistrib.keys.Length > 0)
			{
				particle2.m_Inert *= this.m_InertDistrib.Evaluate(num3);
			}
			if (this.m_RadiusDistrib.keys.Length > 0)
			{
				particle2.m_Radius *= this.m_RadiusDistrib.Evaluate(num3);
			}
			if (this.m_AddAngleScaleDistrib.keys.Length > 0)
			{
				particle2.m_AddAngleScale *= this.m_AddAngleScaleDistrib.Evaluate(num3);
			}
			num3 += num2;
			particle2.m_Damping = Mathf.Clamp01(particle2.m_Damping);
			particle2.m_Elasticity = Mathf.Clamp01(particle2.m_Elasticity);
			particle2.m_Stiffness = Mathf.Clamp01(particle2.m_Stiffness);
			particle2.m_Inert = Mathf.Clamp01(particle2.m_Inert);
			particle2.m_Radius = Mathf.Max(particle2.m_Radius, 0f);
			particle2.m_AddAngleScale = Mathf.Max(particle2.m_AddAngleScale, 0f);
		}
	}

	// Token: 0x0600002F RID: 47 RVA: 0x000045A8 File Offset: 0x000027A8
	public virtual void reloadParameter()
	{
		foreach (global::DynamicBone_Ver01.Particle particle in this.m_Particles)
		{
			particle.m_Damping = this.m_Damping;
			particle.m_Elasticity = this.m_Elasticity;
			particle.m_Stiffness = this.m_Stiffness;
			particle.m_Inert = this.m_Inert;
			particle.m_Radius = this.m_Radius;
			particle.m_AddAngleScale = this.m_AddAngleScale;
			particle.m_Damping = Mathf.Clamp01(particle.m_Damping);
			particle.m_Elasticity = Mathf.Clamp01(particle.m_Elasticity);
			particle.m_Stiffness = Mathf.Clamp01(particle.m_Stiffness);
			particle.m_Inert = Mathf.Clamp01(particle.m_Inert);
			particle.m_Radius = Mathf.Max(particle.m_Radius, 0f);
			particle.m_AddAngleScale = Mathf.Max(particle.m_AddAngleScale, 0f);
		}
	}

	// Token: 0x06000030 RID: 48 RVA: 0x000046B4 File Offset: 0x000028B4
	public virtual global::DynamicBone_Ver01.Particle AppendParticles(global::DynamicBone_Ver01.BoneNode b, int parentIndex, float boneLength)
	{
		global::DynamicBone_Ver01.Particle particle = new global::DynamicBone_Ver01.Particle();
		particle.m_Transform = b.Transform;
		particle.m_bRotationCalc = b.RotationCalc;
		particle.m_ParentIndex = parentIndex;
		if (b.Transform != null)
		{
			particle.m_Position = (particle.m_PrevPosition = b.Transform.position);
			particle.m_InitLocalPosition = b.Transform.localPosition;
			particle.m_InitLocalRotation = b.Transform.localRotation;
			particle.m_InitEuler = b.Transform.localEulerAngles;
			if (parentIndex >= 0)
			{
				this.CalcLocalPosition(particle, this.m_Particles[parentIndex]);
			}
		}
		else
		{
			Transform transform = this.m_Particles[parentIndex].m_Transform;
			if (this.m_EndLength > 0f)
			{
				Transform parent = transform.parent;
				if (parent != null)
				{
					particle.m_EndOffset = transform.InverseTransformPoint(transform.position * 2f - parent.position) * this.m_EndLength;
				}
				else
				{
					particle.m_EndOffset = new Vector3(this.m_EndLength, 0f, 0f);
				}
			}
			else
			{
				particle.m_EndOffset = this.m_EndOffset;
			}
			particle.m_Position = (particle.m_PrevPosition = transform.TransformPoint(particle.m_EndOffset));
		}
		if (parentIndex >= 0)
		{
			boneLength += (this.m_Particles[parentIndex].m_Transform.position - particle.m_Position).magnitude;
			particle.m_BoneLength = boneLength;
			this.m_BoneTotalLength = Mathf.Max(this.m_BoneTotalLength, boneLength);
		}
		this.m_Particles.Add(particle);
		return particle;
	}

	// Token: 0x06000031 RID: 49 RVA: 0x00004870 File Offset: 0x00002A70
	public virtual void InitTransforms()
	{
		foreach (global::DynamicBone_Ver01.Particle particle in this.m_Particles)
		{
			if (particle.m_Transform != null)
			{
				particle.m_Transform.localPosition = particle.m_InitLocalPosition;
				particle.m_Transform.localRotation = particle.m_InitLocalRotation;
			}
		}
	}

	// Token: 0x06000032 RID: 50 RVA: 0x000048F8 File Offset: 0x00002AF8
	public virtual void ResetParticlesPosition()
	{
		this.m_ObjectPrevPosition = base.transform.position;
		foreach (global::DynamicBone_Ver01.Particle particle in this.m_Particles)
		{
			if (particle.m_Transform != null)
			{
				particle.m_Position = (particle.m_PrevPosition = particle.m_Transform.position);
			}
			else
			{
				Transform transform = this.m_Particles[particle.m_ParentIndex].m_Transform;
				particle.m_Position = (particle.m_PrevPosition = transform.TransformPoint(particle.m_EndOffset));
			}
		}
	}

	// Token: 0x06000033 RID: 51 RVA: 0x000049C0 File Offset: 0x00002BC0
	public virtual void UpdateParticles1()
	{
		Vector3 vector = this.m_Gravity;
		vector = (vector + this.m_Force) * this.m_ObjectScale;
		foreach (global::DynamicBone_Ver01.Particle particle in this.m_Particles)
		{
			if (particle.m_ParentIndex >= 0)
			{
				Vector3 a = particle.m_Position - particle.m_PrevPosition;
				Vector3 b = this.m_ObjectMove * particle.m_Inert;
				particle.m_PrevPosition = particle.m_Position + b;
				particle.m_Position += a * (1f - particle.m_Damping) + vector + b;
			}
			else
			{
				particle.m_PrevPosition = particle.m_Position;
				particle.m_Position = particle.m_Transform.position;
			}
		}
	}

	// Token: 0x06000034 RID: 52 RVA: 0x00004AC8 File Offset: 0x00002CC8
	public virtual void UpdateParticles2()
	{
		for (int i = 1; i < this.m_Particles.Count; i++)
		{
			global::DynamicBone_Ver01.Particle particle = this.m_Particles[i];
			global::DynamicBone_Ver01.Particle particle2 = this.m_Particles[particle.m_ParentIndex];
			float num;
			if (particle.m_Transform != null)
			{
				num = (particle2.m_Transform.position - particle.m_Transform.position).magnitude;
			}
			else
			{
				num = particle.m_EndOffset.magnitude * this.m_ObjectScale;
			}
			float num2 = Mathf.Lerp(1f, particle.m_Stiffness, this.m_Weight);
			if (num2 > 0f || particle.m_Elasticity > 0f)
			{
				Matrix4x4 localToWorldMatrix = particle2.m_Transform.localToWorldMatrix;
				localToWorldMatrix.SetColumn(3, particle2.m_Position);
				Vector3 a;
				if (particle.m_Transform != null)
				{
					a = localToWorldMatrix.MultiplyPoint3x4(particle.m_LocalPosition);
				}
				else
				{
					a = localToWorldMatrix.MultiplyPoint3x4(particle.m_EndOffset);
				}
				Vector3 a2 = a - particle.m_Position;
				particle.m_Position += a2 * particle.m_Elasticity;
				if (num2 > 0f)
				{
					a2 = a - particle.m_Position;
					float magnitude = a2.magnitude;
					float num3 = num * (1f - num2) * 2f;
					if (magnitude > num3)
					{
						particle.m_Position += a2 * ((magnitude - num3) / magnitude);
					}
				}
			}
			float particleRadius = particle.m_Radius * this.m_ObjectScale;
			foreach (global::DynamicBoneCollider dynamicBoneCollider in this.m_Colliders)
			{
				if (dynamicBoneCollider != null && dynamicBoneCollider.enabled)
				{
					dynamicBoneCollider.Collide(ref particle.m_Position, particleRadius);
				}
			}
			Vector3 a3 = particle2.m_Position - particle.m_Position;
			float magnitude2 = a3.magnitude;
			if (magnitude2 > 0f)
			{
				particle.m_Position += a3 * ((magnitude2 - num) / magnitude2);
			}
		}
	}

	// Token: 0x06000035 RID: 53 RVA: 0x00004D3C File Offset: 0x00002F3C
	public virtual void SkipUpdateParticles()
	{
		foreach (global::DynamicBone_Ver01.Particle particle in this.m_Particles)
		{
			if (particle.m_ParentIndex >= 0)
			{
				Vector3 b = this.m_ObjectMove * particle.m_Inert;
				particle.m_PrevPosition += b;
				particle.m_Position += b;
				global::DynamicBone_Ver01.Particle particle2 = this.m_Particles[particle.m_ParentIndex];
				float num;
				if (particle.m_Transform != null)
				{
					num = (particle2.m_Transform.position - particle.m_Transform.position).magnitude;
				}
				else
				{
					num = particle.m_EndOffset.magnitude * this.m_ObjectScale;
				}
				float num2 = Mathf.Lerp(1f, particle.m_Stiffness, this.m_Weight);
				if (num2 > 0f)
				{
					Matrix4x4 localToWorldMatrix = particle2.m_Transform.localToWorldMatrix;
					localToWorldMatrix.SetColumn(3, particle2.m_Position);
					Vector3 a;
					if (particle.m_Transform != null)
					{
						a = localToWorldMatrix.MultiplyPoint3x4(particle.m_Transform.localPosition);
					}
					else
					{
						a = localToWorldMatrix.MultiplyPoint3x4(particle.m_EndOffset);
					}
					Vector3 a2 = a - particle.m_Position;
					float magnitude = a2.magnitude;
					float num3 = num * (1f - num2) * 2f;
					if (magnitude > num3)
					{
						particle.m_Position += a2 * ((magnitude - num3) / magnitude);
					}
				}
				Vector3 a3 = particle2.m_Position - particle.m_Position;
				float magnitude2 = a3.magnitude;
				if (magnitude2 > 0f)
				{
					particle.m_Position += a3 * ((magnitude2 - num) / magnitude2);
				}
			}
			else
			{
				particle.m_PrevPosition = particle.m_Position;
				particle.m_Position = particle.m_Transform.position;
			}
		}
	}

	// Token: 0x06000036 RID: 54 RVA: 0x00004F7C File Offset: 0x0000317C
	public virtual void ApplyParticlesToTransforms()
	{
		for (int i = 1; i < this.m_Particles.Count; i++)
		{
			global::DynamicBone_Ver01.Particle particle = this.m_Particles[i];
			global::DynamicBone_Ver01.Particle particle2 = this.m_Particles[particle.m_ParentIndex];
			if (particle2.m_bRotationCalc)
			{
				Vector3 direction;
				if (particle.m_Transform != null)
				{
					direction = particle.m_LocalPosition;
				}
				else
				{
					direction = particle.m_EndOffset;
				}
				Vector3 toDirection = particle.m_Position - particle2.m_Position;
				float num;
				Vector3 axis;
				Quaternion.FromToRotation(particle2.m_Transform.TransformDirection(direction), toDirection).ToAngleAxis(out num, out axis);
				num *= particle.m_AddAngleScale;
				Quaternion lhs = Quaternion.AngleAxis(num, axis);
				particle2.m_Transform.rotation = lhs * particle2.m_Transform.rotation;
			}
			if (particle.m_Transform)
			{
				particle.m_Transform.position = particle.m_Position;
			}
		}
	}

	// Token: 0x06000037 RID: 55 RVA: 0x0000507C File Offset: 0x0000327C
	public virtual void CalcLocalPosition(global::DynamicBone_Ver01.Particle particle, global::DynamicBone_Ver01.Particle parent)
	{
		particle.m_LocalPosition = parent.m_Transform.InverseTransformPoint(particle.m_Position);
	}

	// Token: 0x04000040 RID: 64
	public string comment = string.Empty;

	// Token: 0x04000041 RID: 65
	public Transform m_Root;

	// Token: 0x04000042 RID: 66
	public float m_UpdateRate = 60f;

	// Token: 0x04000043 RID: 67
	[Range(0f, 1f)]
	public float m_Damping = 0.1f;

	// Token: 0x04000044 RID: 68
	public AnimationCurve m_DampingDistrib;

	// Token: 0x04000045 RID: 69
	[Range(0f, 1f)]
	public float m_Elasticity = 0.1f;

	// Token: 0x04000046 RID: 70
	public AnimationCurve m_ElasticityDistrib;

	// Token: 0x04000047 RID: 71
	[Range(0f, 1f)]
	public float m_Stiffness = 0.1f;

	// Token: 0x04000048 RID: 72
	public AnimationCurve m_StiffnessDistrib;

	// Token: 0x04000049 RID: 73
	[Range(0f, 1f)]
	public float m_Inert;

	// Token: 0x0400004A RID: 74
	public AnimationCurve m_InertDistrib;

	// Token: 0x0400004B RID: 75
	public float m_Radius;

	// Token: 0x0400004C RID: 76
	public AnimationCurve m_RadiusDistrib;

	// Token: 0x0400004D RID: 77
	public float m_AddAngleScale = 1f;

	// Token: 0x0400004E RID: 78
	public AnimationCurve m_AddAngleScaleDistrib;

	// Token: 0x0400004F RID: 79
	public float m_EndLength;

	// Token: 0x04000050 RID: 80
	public Vector3 m_EndOffset = Vector3.zero;

	// Token: 0x04000051 RID: 81
	public Vector3 m_Gravity = Vector3.zero;

	// Token: 0x04000052 RID: 82
	public Vector3 m_Force = Vector3.zero;

	// Token: 0x04000053 RID: 83
	public List<global::DynamicBoneCollider> m_Colliders;

	// Token: 0x04000054 RID: 84
	public List<global::DynamicBone_Ver01.BoneNode> m_Nodes;

	// Token: 0x04000055 RID: 85
	protected Vector3 m_ObjectMove = Vector3.zero;

	// Token: 0x04000056 RID: 86
	protected Vector3 m_ObjectPrevPosition = Vector3.zero;

	// Token: 0x04000057 RID: 87
	protected float m_BoneTotalLength;

	// Token: 0x04000058 RID: 88
	protected float m_ObjectScale = 1f;

	// Token: 0x04000059 RID: 89
	protected float m_Time;

	// Token: 0x0400005A RID: 90
	protected float m_Weight = 1f;

	// Token: 0x0400005B RID: 91
	protected List<global::DynamicBone_Ver01.Particle> m_Particles = new List<global::DynamicBone_Ver01.Particle>();

	// Token: 0x0200000A RID: 10
	[Serializable]
	public class BoneNode
	{
		// Token: 0x0400005C RID: 92
		public Transform Transform;

		// Token: 0x0400005D RID: 93
		public bool RotationCalc = true;
	}

	// Token: 0x0200000B RID: 11
	public class Particle
	{
		// Token: 0x0400005E RID: 94
		public Transform m_Transform;

		// Token: 0x0400005F RID: 95
		public int m_ParentIndex = -1;

		// Token: 0x04000060 RID: 96
		public float m_Damping;

		// Token: 0x04000061 RID: 97
		public float m_Elasticity;

		// Token: 0x04000062 RID: 98
		public float m_Stiffness;

		// Token: 0x04000063 RID: 99
		public float m_Inert;

		// Token: 0x04000064 RID: 100
		public float m_Radius;

		// Token: 0x04000065 RID: 101
		public float m_BoneLength;

		// Token: 0x04000066 RID: 102
		public float m_AddAngleScale;

		// Token: 0x04000067 RID: 103
		public bool m_bRotationCalc = true;

		// Token: 0x04000068 RID: 104
		public Vector3 m_Position = Vector3.zero;

		// Token: 0x04000069 RID: 105
		public Vector3 m_PrevPosition = Vector3.zero;

		// Token: 0x0400006A RID: 106
		public Vector3 m_EndOffset = Vector3.zero;

		// Token: 0x0400006B RID: 107
		public Vector3 m_InitLocalPosition = Vector3.zero;

		// Token: 0x0400006C RID: 108
		public Quaternion m_InitLocalRotation = Quaternion.identity;

		// Token: 0x0400006D RID: 109
		public Vector3 m_InitEuler = Vector3.zero;

		// Token: 0x0400006E RID: 110
		public Vector3 m_LocalPosition = Vector3.zero;
	}
}
